
import java.awt.Color;
import java.awt.Font;
import java.util.LinkedList;
import java.util.List;
import java.awt.event.*;
import java.util.Random;

import javax.swing.*;

@SuppressWarnings("serial")
public class GUI extends JFrame implements ActionListener {
	// Initialize everything that ends up on the screen
	public GUI() {
		// Default settings for this frame
		this.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		this.setTitle("Capper");
		
		// Instantiate static objects
		rightPanel = new JPanel();
		picturePanel = new JPanel();
		descriptionPanel = new JPanel();
		selectionPanel = new JPanel();
		displayPicture = new JLabel();
		descriptionText = new JTextArea();
		endButton = new JButton("End Game");
		nextButton = new JButton("Begin");
		choiceGroup = new ButtonGroup();
		choice1 = new JRadioButton();
		choice2 = new JRadioButton();
		choice3 = new JRadioButton();
		
		// Initialize button group
		choiceGroup.add(choice1);
		choiceGroup.add(choice2);
		choiceGroup.add(choice3);
		
		// Prepare action responses
		endButton.addActionListener(this);
		nextButton.addActionListener(this);
		choice1.setSelected(true);
		randomGenerator = new Random();
		
		// Miscellaneous configuration
		descriptionText.setLineWrap(true);
		descriptionText.setWrapStyleWord(true);
		descriptionText.setEditable(false);
		
		// Set the layout manager for each sub-panel
		GroupLayout rightLayout = new GroupLayout(rightPanel);
		GroupLayout pictureLayout = new GroupLayout(picturePanel);
		GroupLayout descriptionLayout = new GroupLayout(descriptionPanel);
		GroupLayout selectionLayout = new GroupLayout(selectionPanel);
		rightPanel.setLayout(rightLayout);
		picturePanel.setLayout(pictureLayout);
		descriptionPanel.setLayout(descriptionLayout);
		selectionPanel.setLayout(selectionLayout);
		picturePanel.setBorder(BorderFactory.createEtchedBorder());
		descriptionPanel.setBorder(BorderFactory.createEtchedBorder());
		selectionPanel.setBorder(BorderFactory.createEtchedBorder());
		
		// Arrange the picture panel's contents
		pictureLayout.setAutoCreateGaps(true);
		pictureLayout.setAutoCreateContainerGaps(true);
		pictureLayout.setHorizontalGroup(
				pictureLayout.createSequentialGroup()
					.addComponent(displayPicture)
		);
		pictureLayout.setVerticalGroup(
				pictureLayout.createSequentialGroup()
					.addComponent(displayPicture)
		);
		
		// Arrange the description panel's contents
		descriptionLayout.setAutoCreateGaps(true);
		descriptionLayout.setAutoCreateContainerGaps(true);
		descriptionLayout.setHorizontalGroup(
				descriptionLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
					.addComponent(descriptionText, 200, 200, 200)
					.addComponent(endButton)
		);
		descriptionLayout.setVerticalGroup(
				descriptionLayout.createSequentialGroup()
							.addComponent(descriptionText)
							.addComponent(endButton)
		);
		
		// Arrange the selection panel's contents
		selectionLayout.setAutoCreateGaps(true);
		selectionLayout.setAutoCreateContainerGaps(true);
		selectionLayout.setHorizontalGroup(
				selectionLayout.createSequentialGroup()
					.addGroup(selectionLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
							.addComponent(choice1)
							.addComponent(choice2)
							.addComponent(choice3)
					)
					.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
					.addGroup(selectionLayout.createParallelGroup()
							.addComponent(nextButton)
				)
		);
		selectionLayout.setVerticalGroup(
				selectionLayout.createSequentialGroup()
					.addComponent(choice1)
					.addComponent(choice2)
					.addComponent(choice3)
					.addComponent(nextButton)
		);
		
		// Set up the hidden right panel just for size matching purposes
		rightLayout.setAutoCreateGaps(true);
		rightLayout.setHorizontalGroup(
				rightLayout.createParallelGroup()
					.addComponent(picturePanel)
					.addComponent(selectionPanel)
		);
		rightLayout.setVerticalGroup(
				rightLayout.createSequentialGroup()
					.addComponent(picturePanel)
					.addComponent(selectionPanel)
		);
		
		// Arrange the container's contents
		GroupLayout masterLayout = new GroupLayout(getContentPane());
		getContentPane().setLayout(masterLayout);
		masterLayout.setAutoCreateGaps(true);
		masterLayout.setAutoCreateContainerGaps(true);
		masterLayout.setHorizontalGroup(
				masterLayout.createSequentialGroup()
					.addComponent(descriptionPanel)
					.addComponent(rightPanel)
		);
		masterLayout.setVerticalGroup(
				masterLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
					.addComponent(descriptionPanel)
					.addComponent(rightPanel)
		);
		
		// Link sets of panels together for fitting to the window
		rightLayout.linkSize(SwingConstants.HORIZONTAL, picturePanel, selectionPanel);
		masterLayout.linkSize(SwingConstants.VERTICAL, descriptionPanel, rightPanel);
		
		// Curiously, this prevents the window from making itself too large later on
		this.pack();
	}
		
	// Sun Java tutorial example plus extra code for resizing to static desired dimensions
	private ImageIcon createImageIcon(String path, String description) {
		java.net.URL imgURL = getClass().getResource(path);
		if (imgURL != null) {
			ImageIcon tmp = new ImageIcon(imgURL, description);
			tmp.setImage(tmp.getImage().getScaledInstance(640, 480, java.awt.image.BufferedImage.SCALE_SMOOTH));
			return tmp;
		} else {
			System.err.println("Couldn't find file: " + path);
			return null;
		}
	}
	
	// Respond by recording which type of answer was provided: good/meh/bad
	// Also respond to the next and end game buttons
	public void actionPerformed (ActionEvent e) {
		System.out.print("Notifying of action command " + e.getActionCommand() + '\n');
		Sys.eventNotify(e.getActionCommand());
	}
	
	public String getChoice() {
		return choiceGroup.getSelection().getActionCommand();
	}
	
	// Disable radio buttons
	// Set next button to begin the game
	// Set up the End Game button
	// Prepare initial image and description
	protected void backStoryScreen() {
		choice1.setVisible(false);
		choice2.setVisible(false);
		choice3.setVisible(false);
		
		endButton.setActionCommand(endCommand);
		nextButton.setText("Begin");
		nextButton.setActionCommand(nextCommand);
		
		descriptionText.setText(gameMessages[0]);
                Font font = new Font("Verdana", Font.BOLD, 16);
                descriptionText.setFont(font);
                descriptionText.setForeground(Color.BLUE);
		displayPicture.setIcon(createImageIcon("images/101.jpg", ""));
		
		this.pack();
	}
	
	// Decide random button response ordering
	// Prepare image, button text, description text
	// Enable radio buttons
	protected void stopOilSpillScreen(int seed) {
		choice1.setSelected(true);
		System.out.print("StopOilSpillScreen seed " + Integer.toString(seed) + '\n');
		
		displayPicture.setIcon(
				createImageIcon(
						String.format(
								"images/%1$02d.jpg",
								(1 + (4 * seed))
						),
						""
				)
		);
		descriptionText.setText(descriptionData[seed]);
		nextButton.setText("Next");
		
		choice1.setVisible(true);
		choice2.setVisible(true);
		choice3.setVisible(true);

		LinkedList<String[]> temp = new LinkedList<String[]>();
		temp.add(new String[]{goodCommand, choices[seed][0]});
		temp.add(new String[]{mehCommand, choices[seed][1]});
		temp.add(new String[]{badCommand, choices[seed][2]});
		
		// Some semblance of randomized placement
		// This could be expanded in the future to an arbitrary list of buttons
		int random = randomGenerator.nextInt(temp.size());
		choice1.setActionCommand(temp.get(random)[0]);
		choice1.setText(temp.get(random)[1]);
		temp.remove(random);
		
		random = randomGenerator.nextInt(temp.size());
		choice2.setActionCommand(temp.get(random)[0]);
		choice2.setText(temp.get(random)[1]);
		temp.remove(random);
		
		choice3.setActionCommand(temp.getFirst()[0]);
		choice3.setText(temp.getFirst()[1]);
		
		this.pack();
	}
	
	// Disable buttons
	// Display educate text
	protected void educateUserScreen(int seed) {
		choice1.setVisible(false);
		choice2.setVisible(false);
		choice3.setVisible(false);
		
		int seedUpper = seed >> 2;
		int seedLower = seed & 3;
		
		displayPicture.setIcon(
				createImageIcon(
						String.format(
								"images/%1$02d.jpg",
								(1 + (4 * seedUpper) + seedLower)
						),
						""
				)
		);
		descriptionText.setText(responses[seedUpper][seedLower + 1]);
		
		this.pack();
	}
	
	protected void gameLogScreen() {
		
		this.pack();
	}
	
	protected void finishGameScreen() {
		
		this.pack();
	}
	
	final static String nextCommand = "NEXT";
	final static String endCommand = "END";
	final static String goodCommand = "GOOD";
	final static String mehCommand = "MEH";
	final static String badCommand = "BAD";
	
	// Fills in the descriptionText during each StopOilSpill use
	final static String[] descriptionData = {
			"The spill has destroyed many local jobs and will need repaired.",
			"The oil rig that broke and caused the spill needs removed from the ocean.",
			"The oil that is staying under the water's surface needs to be removed.",
			"Lots of oil has reached the shoreline and it needs to be cleaned.",
			"The ocean wildlife is being affected by the oil spill and they need rescue.",
			"The land-based wildlife have been affected and need to be cleaned.",
			"There is oil floating on the water's surface and it needs removed.",
			"The pipe where the oil is coming from needs capped.",
			"You've removed quite a bit of oil from the ecosystem and it needs dealt with.",
			"A fire has started on the oil and needs put out."
		};
	
	// Fills in the radio button texts during each StopOilSpill use
	final static String[][] choices = {
				{
					"Put out of work people to work cleaning the spill",
					"Provide compensation fund",
					"Let the economy fix itself"
				},
				{
					"Collect and recycle the debris",
					"Collect it, and take it to the dump",
					"Let it sink"
				},
				{
					"Use bio-remediation: where organisms are used to naturally clean the oil.",
					"Use vacuum ships to suck up the oil",
					"Wait for it to float to the surface"
				},
				{
					"Clean the sand, then bring it back to the shore after cleaning",
					"Remove and properly dispose of affected sand",
					"Put new sand on oil-covered sand"
				},
				{
					"Capture affected wildlife, clean in the lab, return to cleaned habitat",
					"Clean the wildlife and return them to ocean",
					"Don't worry about this wildlife, it will just die and make a new reef"
				},
				{
					"Capture and clean the wildlife and return to cleaned beaches",
					"Clean the wildlife and move them to new habitat",
					"Try and clone the affected species to replace them"
				},
				{
					"Use oil skimming boats owned by the affected residents",
					"Use oil skimming boats owned by private company",
					"Let all the oil float to the shore before cleaning"
				},
				{
					"Use robots to safely weld a cap on the pipe",
					"Use divers to cap the well",
					"Use dead wildlife to clog pipe"
				},
				{
					"Recycle collected oil and use to power cleaning ships",
					"Recycle oil and sell in the market",
					"Dump the oil in a landfill"
				},
				{
					"Surround oil and use firefighting ships to put our fire ASAP",
					"Surround oil and let the fire go out on its own",
					"Put out fire with more oil"
				}
		};

	// Fills in the descriptionText during each EducateUser use
	final static String[][] responses = {
				{
					"Correct!",
					"This may help a little bit, but it won't recreate lost jobs.",
					"This method cannot work because regular citizens don't have to funds to recreate their jobs."
				},
				{
					"Correct!",
					"This is partially correct, but it would be better to recycle the debris.",
					"This is not a good solution.  It will hurt the ocean life."

				},
				{
					"Correct!",
					"This method will partially work, but it won't get all of the oil.",
					"This is not a good idea - a lot of wildlife will be harmed with this method."

				},
				{
					"Correct!",
					"This method is alright, but re-using the sand is a better idea.",
					"This method will not work, as the oil will just resurface."

				},
				{
					"Correct!",
					"This will not really work because the cleanup has not finished.",
					"This idea is not good, as it will destroy the ecosystem."

				},
				{
					"Correct!",
					"This will not necessarily work, because some wildlife can't successfully be relocated.",
					"This method will not work, as cloning animals makes infertile offspring."

				},
				{
					"Correct!",
					"This idea will work, but it's not putting the affected citizens to work.",
					"This method will not work, as many wildlife will be killed."

				},
				{
					"Correct!",
					"This is very unsafe for the divers, so robots are recommended.",
					"This method will not actually stop the leak and is quite inhumane."

				},
				{
					"Correct!",
					"This method is okay, but is quite greedy.",
					"This method is very wasteful and not the best choice."

				},
				{
					"Correct!",
					"This method might work, but is very dangerous to humans and wildlife alike.",
					"This will not actually put out the fire."
				}
		};
		
	// Fills in the descriptionText at the end of the game
	final static String[] gameMessages = {
				"An oil rig has been damaged and a pipe is leaking oil under the water's surface.  Many scenarios will be given to you, and you will need to choose the best of 3 choices.  If you choose the wrong choice too many times, you will lose and the oil will get out of control.  If you choose the correct choice, then eventually you will stop the oil spill and have cleaned the surrounding area.  Good Luck!",
				"You have successfully stopped the oil spill and cleaned up the surrounding area.  Congratulations!",
				"You were unsuccessful in stopping the oil spill and cleaning up the surrounding area.  Try again."
		};
		
	// Our three basic panels that exist on every screen, plus one extra for appearance
	private JPanel rightPanel, picturePanel, descriptionPanel, selectionPanel;
	
	// The only thing in the picture panel, on every screen
	private JLabel displayPicture;
	
	// In the left panel, on every screen, show some back story or info
	private JTextArea descriptionText;
	
	// In the left panel, on every screen, a button that ends the current game
	// In the bottom panel, on every screen, a button proceeds to the next screen
	private JButton endButton, nextButton;

	// Only on StopOilSpill screens, show this radio button group
	private ButtonGroup choiceGroup;
	private JRadioButton choice1, choice2, choice3;
	private Random randomGenerator;
}
